home *** CD-ROM | disk | FTP | other *** search
/ Die Speccy' 97 / Die Speccy' 97.iso / amiga_system / the_aminet / util / boot / snap_v2_0.lha / Snap / SnapGfx.c < prev    next >
C/C++ Source or Header  |  1995-09-13  |  11KB  |  475 lines

  1. /*
  2.  *    $VER:SnapGfx.c - (11.09.95) 17:39:11 Copyright ⌐ 1995 by Mikael Karlsson & Sylvain ROUGIER
  3.  *
  4.  *      Created: 1988
  5.  *      Modified:    11 Sep 1995    17:39:11
  6.  *
  7.  *      Make>> smake
  8.  *
  9.  * 09/09/95:
  10.  *        fix, to save 8bit per gun palette under V39+
  11.  *
  12.  *    10/09/95:
  13.  *        Now Alloc dynamaicaly BitMap struct. (future usage of AllocBitMap())
  14.  */
  15.  
  16. #include "Snap.h"
  17.  
  18. #include "proto/Misc.h"
  19. #include "proto/GfxSnap.h"
  20.  
  21. IMPORT BOOL Kick36;
  22.  
  23. IMPORT struct GfxBase *GfxBase;
  24.  
  25. IMPORT struct SnapRsrc *SnapRsrc;
  26. IMPORT struct Image DiskImage;
  27. IMPORT struct Image ClipImage;
  28. IMPORT struct Gadget DiskGad;
  29. IMPORT struct Gadget ClipGad;
  30. IMPORT struct Gadget VProp, HProp;
  31. IMPORT struct PropInfo VInfo, HInfo;
  32. IMPORT struct Image VImage, HImage;
  33. IMPORT struct NewWindow Nw;
  34. IMPORT UBYTE *WindowTitle;
  35.  
  36. IMPORT LONG xl;            /* leftmost x position */
  37. IMPORT LONG xr;            /* rightmost x position */
  38. IMPORT LONG yt;            /* topmost y position */
  39. IMPORT LONG yb;            /* bottommost y position */
  40. IMPORT LONG mx, my;        /* Mouse position in pixels */
  41.  
  42. #define GfxFrame 4L
  43. IMPORT Point OldFrame[ ];
  44. IMPORT Point NewFrame[ ];
  45. IMPORT LONG OFType;        /* Old frame type: ShortFrame/LongFrame */
  46. IMPORT UWORD Ptrn;
  47. IMPORT WORD Pattern[ ];
  48.  
  49. IMPORT struct RastPort MyRP;
  50. IMPORT struct BitMap MyBM;
  51. IMPORT struct Screen *theScreen;
  52. IMPORT struct RastPort rp;
  53.  
  54. IMPORT struct timerequest MyTR;
  55.  
  56. IMPORT LONGBITS cancelsignal, donesignal, movesignal;
  57. IMPORT LONGBITS clicksignal, ticksignal, timersignal;
  58. IMPORT WORD action;
  59.  
  60. LONG TopBar;
  61. LONG LeftBar;
  62. LONG RightBar;
  63. LONG BottomBar;
  64. LONG ScreenFontHeight;
  65. struct TextFont *ScreenFont;
  66.  
  67. VOID FixHeights( )
  68. {
  69.     struct Screen WBScreen;
  70.  
  71.     OpenWorkBench( );
  72.     if ( GetScreenData( ( char *)&WBScreen, ( LONG) sizeof ( struct Screen), WBENCHSCREEN, NULL))
  73.     {
  74.         /* Now this is a good practice */
  75.         TopBar = WBScreen.WBorTop + WBScreen.RastPort.TxHeight + 1;
  76.         LeftBar = WBScreen.WBorLeft;
  77.         RightBar = WBScreen.WBorRight;
  78.         BottomBar = WBScreen.WBorBottom;
  79.         ScreenFont = WBScreen.RastPort.Font;
  80.         if ( !ScreenFont)
  81.         {
  82.             Forbid( );
  83.             ScreenFont = GfxBase->DefaultFont;
  84.             Permit( );
  85.         }
  86.         ScreenFontHeight = ScreenFont->tf_YSize;
  87.     }
  88.     else
  89.     {
  90.         /* Sorry, but I don't realise how this could fail.
  91.            Well, if we're snapping on another screen and
  92.            WB is closed and it can't be opened by GetScreenData( )...
  93.            Anyway, IF this should happen -- Use Topaz 8 */
  94.         TopBar = 10;
  95.         LeftBar = 2;
  96.         RightBar = 2;
  97.         BottomBar = 1;
  98.         ScreenFontHeight = 8;
  99.         Forbid( );
  100.         ScreenFont = GfxBase->DefaultFont;
  101.         Permit( );
  102.     }
  103. }
  104.  
  105.  
  106. struct GfxSnap *CreateGfxSnap( void)
  107. {
  108.     struct GfxSnap *GfxSnap;
  109.  
  110.     if ( GfxSnap = AllocVec( sizeof( struct GfxSnap), MEMF_ANY|MEMF_CLEAR))
  111.     {
  112.         return GfxSnap;
  113.     }
  114.  
  115.     return NULL;
  116. }
  117.  
  118. void DeleteGfxSnap( struct GfxSnap *GfxSnap)
  119. {
  120.     if ( GfxSnap)
  121.     {
  122.         if ( GfxSnap->BitMap)
  123.         {
  124.             Snp_FreeBitMap( GfxSnap->BitMap, GfxSnap->width, GfxSnap->height);
  125.         }
  126.         FreeVec( GfxSnap);
  127.     }
  128.  
  129.     return;
  130. }
  131.  
  132. static void CopyColorDefs( ULONG Depth, struct ColorMap *ColorMap, UBYTE RGB8[][3])
  133. {
  134.     ULONG i = Depth;
  135.  
  136.     if ( SysBase->LibNode.lib_Version < 39)
  137.     {
  138.         ULONG col;
  139.  
  140.         while ( i-- && ( col = GetRGB4( ColorMap, i)) != -1L)
  141.         {
  142.             RGB8[ i][ 0] = RGB4ToRR( col);
  143.             RGB8[ i][ 1] = RGB4ToGG( col);
  144.             RGB8[ i][ 2] = RGB4ToBB( col);
  145.         }
  146.     }
  147.     else
  148.     {
  149.         while ( i--)
  150.         {
  151.             ULONG RGB[ 3];
  152.  
  153.             GetRGB32( ColorMap, i, 1, RGB);
  154.             RGB8[ i][ 0] = RGB32ToRGB8( RGB[ 0]);
  155.             RGB8[ i][ 1] = RGB32ToRGB8( RGB[ 1]);
  156.             RGB8[ i][ 2] = RGB32ToRGB8( RGB[ 2]);
  157.         }
  158.     }
  159. }
  160.  
  161. /* SnapGfx is the actual graphics snapper.
  162.    ** It steals the bitmap data from the given rastport
  163.    ** and puts it in a separate bitmap.
  164.    ** It also prepares the NewWindow structure according
  165.    ** to the snapped bitmap.
  166.    ** The coordinates are assumed to be valid.
  167.  */
  168. struct GfxSnap * SnapGfx( struct RastPort *rp)
  169. {
  170.     struct GfxSnap *GS;
  171.     LONG i;
  172.  
  173.     GS = CreateGfxSnap();
  174.     if ( !GS)
  175.     {
  176.         return NULL;
  177.     }
  178.  
  179.     GS->x = xl;
  180.     GS->y = yt;
  181.     GS->width = xr - xl + 1;
  182.     GS->height = yb - yt + 1;
  183.     if ( xr < xl + MINWIDTH)
  184.     {            /* Can't have too small windows */
  185.         xr = xl + MINWIDTH;
  186.     }
  187.     if ( yb < yt + MINHEIGHT)
  188.     {
  189.         yb = yt + MINHEIGHT;
  190.     }
  191.     GS->depth = rp->BitMap->Depth;
  192.     GS->viewmode = theScreen->ViewPort.Modes;
  193.     GS->pagew = theScreen->Width;
  194.     GS->pageh = theScreen->Height;
  195.     i = ( GS->viewmode & HAM ? 16 : 1L << GS->depth);
  196.     /* Copy the color map in case we should need it later */
  197.     CopyColorDefs(
  198.         GS->viewmode & HAM ?
  199.             16 :
  200.             1L << GS->depth,
  201.         theScreen->ViewPort.ColorMap,
  202.         GS->rgb);
  203.  
  204.     /* Set up a nice bitmap */
  205.     InitRastPort( &MyRP);
  206.     MyRP.BitMap = GS->BitMap = AllocBitMap( GS->width, GS->height, GS->depth, BMF_DISPLAYABLE, rp->BitMap);
  207.     if ( !GS->BitMap)
  208.     {
  209.         DeleteGfxSnap( GS);
  210.         return NULL;
  211.     }
  212.  
  213.     /* Copy the selected part of the screen */
  214.     ClipBlit( rp, xl, yt, &MyRP, 0L, 0L, GS->width, GS->height, 0xC0L);
  215.     if ( !Kick36)
  216.     {
  217.         VInfo.Flags |= PROPBORDERLESS;
  218.         HInfo.Flags |= PROPBORDERLESS;
  219.     }
  220.     CopyMem( ( char *)&DiskGad, ( char *)&GS->DiskGad, ( LONG) sizeof ( DiskGad) + sizeof ( ClipGad) + sizeof ( VProp) + sizeof ( HProp) + sizeof ( VInfo) + sizeof ( HInfo) + sizeof ( VImage) + sizeof ( HImage));
  221.     GS->topbar = TopBar;
  222.     GS->leftbar = LeftBar;
  223.     GS->rightbar = 18;    /* ( Kick36 ? RightBar : 18); */
  224.     GS->bottombar = 10;
  225.  
  226.     Nw.LeftEdge = xl;
  227.     Nw.TopEdge = yt;
  228.     Nw.Width = xr - xl + 1 + GS->leftbar + GS->rightbar;
  229.     Nw.Height = yb - yt + 1 + GS->topbar + GS->bottombar;
  230.     Nw.Flags &= ~( SIMPLE_REFRESH | SMART_REFRESH | NOCAREREFRESH);
  231.     Nw.Flags |= ( SnapRsrc->flags & SIMPLEREFRESH ?
  232.         SIMPLE_REFRESH :
  233.         SMART_REFRESH | NOCAREREFRESH);
  234.  
  235.     Nw.Title = WindowTitle;
  236.     Nw.MinWidth = MINWIDTH + 1 + GS->leftbar + GS->rightbar;
  237.     Nw.MinHeight = MINHEIGHT + 1 + GS->topbar + GS->bottombar;
  238.     Nw.MaxWidth = Nw.Width;
  239.     Nw.MaxHeight = Nw.Height;
  240.  
  241.     if ( Kick36)
  242.         Nw.Flags |= SIZEBBOTTOM | SIZEBRIGHT;
  243.  
  244.     return GS;
  245. }
  246.  
  247. VOID ExtendGfx( )
  248. {
  249.     /* Fix which row we're talking about */
  250.     if ( my - yt < yb - my)
  251.     {            /* Find closest row */
  252.         yt = my;    /* change top row */
  253.     }
  254.     else
  255.     {
  256.         yb = my;    /* change bottom row */
  257.     }
  258.     if ( mx - xl < xr - mx)
  259.     {
  260.         xl = mx;
  261.     }
  262.     else
  263.     {
  264.         xr = mx;
  265.     }
  266. }
  267.  
  268. VOID gfx_frame( )
  269. {
  270.     NewFrame[ 0].x = xl;
  271.     NewFrame[ 0].y = yt;
  272.     NewFrame[ 1].x = xr;
  273.     NewFrame[ 1].y = yt;
  274.     NewFrame[ 2].x = xr;
  275.     NewFrame[ 2].y = yb;
  276.     NewFrame[ 3].x = xl;
  277.     NewFrame[ 3].y = yb;
  278.     NewFrame[ 4].x = xl;
  279.     NewFrame[ 4].y = yt;
  280.     draw_frame( GfxFrame);
  281. }
  282.  
  283. WORD HandleGfx( void)
  284. {
  285.     struct Layer_Info *LockedLayerInfo;
  286.  
  287.     theScreen = WhichScreen( );    /* Find out where we are */
  288.     if ( !theScreen)
  289.     {    /* Don't know? Forget it. */
  290.         action = noaction;
  291.         return 0;
  292.     }
  293.     /* Lock everything - find out what happens */
  294.     LockedLayerInfo = &theScreen->LayerInfo;
  295. //    LockLayers( LockedLayerInfo);
  296.  
  297.     /* Get a copy. Don't mess with somebody else's RP. */
  298.     CopyMem( ( char *)&theScreen->RastPort, ( char *)&rp, ( long)sizeof ( struct RastPort));
  299.  
  300.     SetDrMd( &rp, COMPLEMENT);
  301.  
  302.     xl = theScreen->MouseX + theScreen->ViewPort.RasInfo->RxOffset;
  303.     if ( xl < 0)
  304.     {
  305.         xl = 0;
  306.     }
  307.     if ( xl >= theScreen->Width)
  308.     {    /* Check those corners. Check those corners. */
  309.         xl = theScreen->Width - 1;
  310.     }
  311.     yt = theScreen->MouseY + theScreen->ViewPort.RasInfo->RyOffset;
  312.     if ( yt < 0)
  313.     {
  314.         yt = 0;
  315.     }
  316.     if ( yt >= theScreen->Height)
  317.     {
  318.         yt = theScreen->Height - 1;
  319.     }
  320.     xr = xl;
  321.     yb = yt;
  322.     Ptrn = ( SnapRsrc->CrawlPtrn ? SnapRsrc->CrawlPtrn : Pattern[ UNIT_FRAME]);
  323.     OFType = 0L;
  324.     gfx_frame( );
  325.  
  326.     FOREVER
  327.     {
  328.         REGISTER LONGBITS sig;
  329.  
  330.         MyTR.tr_time.tv_secs = 0;
  331.         MyTR.tr_time.tv_micro = 500000;
  332.         MyTR.tr_node.io_Command = TR_ADDREQUEST;
  333.         SendIO( ( struct IORequest *)&MyTR);
  334.  
  335.         sig = Wait( movesignal | clicksignal | cancelsignal | donesignal | ticksignal | timersignal);
  336.  
  337.         if ( CheckIO( ( struct IORequest *)&MyTR))
  338.         {
  339.             WaitIO( ( struct IORequest *)&MyTR);
  340.             erase_frame( );
  341. //            UnlockLayers( LockedLayerInfo);    /* Unlock things */
  342.             sig = Wait( ticksignal);        /* Wait for input handler to become avtive */
  343. //            LockLayers( LockedLayerInfo);    /* Re-lock */
  344.             /* I guess I should check to see that the window is still
  345.                there. Aw, what the heck. Apologies to anyone who gets
  346.                bitten by this. */
  347.             DisplayBeep( NULL);
  348.             gfx_frame( );
  349.         }
  350.         else
  351.         {
  352.             AbortIO( ( struct IORequest *)&MyTR);
  353.             WaitIO( ( struct IORequest *)&MyTR);
  354.             SetSignal( 0, timersignal);
  355.         }
  356.  
  357.         if ( ( sig & ticksignal) && ( SnapRsrc->CrawlPtrn != 0xffff))
  358.         {
  359.             crawl_frame( 1L);
  360.         }
  361.  
  362.         if ( sig & movesignal || sig & clicksignal)
  363.         {
  364.             mx = theScreen->MouseX + theScreen->ViewPort.RasInfo->RxOffset;
  365.             if ( mx < 0)
  366.             {
  367.                 mx = 0;
  368.             }
  369.             if ( mx >= theScreen->Width)
  370.             {
  371.                 mx = theScreen->Width - 1;
  372.             }
  373.             my = theScreen->MouseY + theScreen->ViewPort.RasInfo->RyOffset;
  374.             if ( my < 0)
  375.             {
  376.                 my = 0;
  377.             }
  378.             if ( my >= theScreen->Height)
  379.             {
  380.                 my = theScreen->Height - 1;
  381.             }
  382.             ExtendGfx( );
  383.             gfx_frame( );
  384.         }
  385.         if ( sig & cancelsignal)
  386.         {    /* Cancelled? */
  387.             erase_frame( );
  388. //            UnlockLayers( LockedLayerInfo);
  389.             return 0;
  390.         }
  391.         if ( sig & donesignal)
  392.         {    /* Finished. Copy gfx. */
  393.             struct GfxSnap *GS;
  394.  
  395.             erase_frame( );
  396.             if ( xl == xr || yt == yb)
  397.             {
  398.                 action = noaction;
  399. //                UnlockLayers( LockedLayerInfo);
  400.                 return 0;
  401.             }
  402.             if ( xr >= theScreen->Width)
  403.             {
  404.                 xl -= xr - theScreen->Width - 1;
  405.                 xr = theScreen->Width - 1;
  406.             }
  407.             if ( yb >= theScreen->Height)
  408.             {
  409.                 yt -= yb - theScreen->Height - 1;
  410.                 yb = theScreen->Height - 1;
  411.             }
  412.             FixHeights( );
  413.             GS = SnapGfx( &rp);    /* Snap! */
  414. //            UnlockLayers( LockedLayerInfo);
  415.             if ( GS)
  416.             {
  417.                 if ( GS->window = opensharedwindow( &Nw))
  418.                 {
  419.                     if ( SnapRsrc->flags & SIMPLEREFRESH)
  420.                     {
  421.                         ModifyIDCMP( GS->window,
  422.                                 GS->window->IDCMPFlags | REFRESHWINDOW);
  423.                     }
  424.                     if ( Kick36)
  425.                     {
  426.                         GS->topbar = GS->window->BorderTop;
  427.                         GS->leftbar = GS->window->BorderLeft;
  428.                         GS->rightbar = GS->window->BorderRight;
  429.                         GS->bottombar = 10;    /*GS->window->BorderBottom; */
  430.  
  431.                         GS->HProp.TopEdge = -7;
  432.                         GS->HProp.Height = 6;
  433.                     }
  434.  
  435.                     GS->DiskGad.TopEdge = GS->topbar;
  436.                     GS->DiskGad.LeftEdge = ( Kick36 ? -17 : -14);
  437.                     GS->DiskGad.Width = ( Kick36 ? 18 : 14);
  438.                     GS->ClipGad.TopEdge = GS->DiskGad.TopEdge + 12;
  439.                     GS->ClipGad.LeftEdge = ( Kick36 ? -17 : -14);
  440.                     GS->ClipGad.Width = ( Kick36 ? 18 : 14);
  441.                     GS->HProp.GadgetRender = ( APTR) & GS->HImage;
  442.                     GS->HProp.SpecialInfo = ( APTR) & GS->HInfo;
  443.                     GS->VProp.TopEdge =
  444.                         GS->ClipGad.TopEdge + ( Kick36 ? 14 : 15);
  445.                     GS->VProp.LeftEdge = ( Kick36 ? 5 : 7) - GS->rightbar;
  446.                     GS->VProp.Width = GS->rightbar - ( Kick36 ? 8 : 10);
  447.                     GS->VProp.Height =
  448.                         ( Kick36 ? -28 : -27) - GS->bottombar - GS->topbar;
  449.                     GS->VProp.GadgetRender = ( APTR) & GS->VImage;
  450.                     GS->VProp.SpecialInfo = ( APTR) & GS->VInfo;
  451.  
  452.                     GS->DiskGad.NextGadget = &GS->ClipGad;
  453.                     GS->ClipGad.NextGadget = &GS->VProp;
  454.                     GS->VProp.NextGadget = &GS->HProp;
  455.                     GS->HProp.NextGadget = NULL;
  456.  
  457.                     AddGList( GS->window, &GS->DiskGad, -1, -1, NULL);
  458.                     GS->window->UserData = ( BYTE *) GS;
  459.                     /* Put gfx in our new window */
  460.                     AdjustSize( GS);
  461.                 }
  462.                 else
  463.                 {
  464.                     DeleteGfxSnap( GS);
  465.                 }
  466.             }
  467.             else
  468.             {    /* Good question */
  469.             }
  470.             action = noaction;
  471.             return 0;
  472.         }
  473.     }
  474. }
  475.